package com.gyy.jLibModbus;

import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;

import java.net.InetAddress;


/**
 * @Author gmd
 * @Description modbus通讯，使用jlibmodbus框架读取slave数据
 * @Date 2021-12-10 14:24:46
 */
public class JLibModbusRead {

    public static ModbusMaster master;

    /**
     * 初始化连接modbus Master主机
     */
    public static void initConnect() throws Exception {
        // 设置主机TCP参数
        TcpParameters tcpParameters = new TcpParameters();
        // 设置TCP的ip地址
        InetAddress address = InetAddress.getByName("127.0.0.1");

        /**
         * 如果是本机localhost的话，可以直接使用
         * tcpParameters.setHost(InetAddress.getLocalHost());
         */

        // TCP参数设置ip地址
        tcpParameters.setHost(address);
        // TCP设置长连接
        tcpParameters.setKeepAlive(true);
        // TCP设置端口，这里设置是默认端口502
        tcpParameters.setPort(Modbus.TCP_PORT);

        // 创建一个主机
        master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
        // 设置事务ID自动递增
        Modbus.setAutoIncrementTransactionId(true);

        if (!master.isConnected()) {
            // 开启连接
            master.connect();
        }
    }


    /**
     * 关闭连接
     */
    public static void closeConnect() throws Exception {
        master.disconnect();
    }


    /**
     * 批量读取Coil线圈（0x01）布尔数据
     *
     * @param slaveId  从机ID
     * @param offset   开始地址
     * @param quantity 读取数量
     */
    public static void readCoils(int slaveId, int offset, int quantity) throws Exception {
        boolean[] coilValues = master.readCoils(slaveId, offset, quantity);

        System.out.println("\nCoil线圈（0x01）布尔数据如下：");
        for (boolean value : coilValues) {
            System.out.println("Address: " + offset++ + ", Value: " + value);
        }
    }


    /**
     * 批量读取Discrete离散量输入（0x02）布尔数据
     *
     * @param slaveId  从机ID
     * @param offset   开始地址
     * @param quantity 读取数量
     */
    public static void readDiscrete(int slaveId, int offset, int quantity) throws Exception {
        boolean[] coilValues = master.readDiscreteInputs(slaveId, offset, quantity);

        System.out.println("\nDiscreteInputs离散量输入（0x02）布尔数据如下：");
        for (boolean value : coilValues) {
            System.out.println("Address: " + offset++ + ", Value: " + value);
        }
    }

    /**
     * 批量读取HoldingRegisters寄存器（0x03）数据
     *
     * @param slaveId  从机ID
     * @param offset   开始地址
     * @param quantity 读取数量
     */
    public static void readHoldingRegisters(int slaveId, int offset, int quantity) throws Exception {
        int[] registerValues = master.readHoldingRegisters(slaveId, offset, quantity);

        System.out.println("\nHoldingRegisters寄存器（0x03）数据如下：");
        for (int value : registerValues) {
            System.out.println("Address: " + offset++ + ", Value: " + value);
        }
    }


    /**
     * 批量读取InputRegister寄存器（0x04）数据
     *
     * @param slaveId  从机ID
     * @param offset   开始地址
     * @param quantity 读取数量
     */
    public static void readInputRegisters(int slaveId, int offset, int quantity) throws Exception {
        int[] registerValues = master.readInputRegisters(slaveId, offset, quantity);

        System.out.println("\nInputRegister寄存器（0x04）数据如下：");
        for (int value : registerValues) {
            System.out.println("Address: " + offset++ + ", Value: " + value);
        }
    }


    public static void main(String[] args) throws Exception {
        initConnect();

        readCoils(1, 0, 10);

        readDiscrete(2, 0, 10);

        readHoldingRegisters(3, 0, 10);

        readInputRegisters(4, 0, 10);

        closeConnect();

    }
}
